package com.wzw.expression.expression.invocation;

import org.springframework.util.ObjectUtils;

import java.lang.reflect.Method;

/**
 * 运行过程中被代理的对象和参数方法
 *
 * @author Wangzhiwen
 */
public abstract class OperationInvocationContext {
    protected final OperationInvocationMetadata metadata;
    protected final Object target;
    protected final Object[] args;
    protected Object result;
    protected Throwable exception;

    public OperationInvocationContext(OperationInvocationMetadata metadata, Object target, Object[] args) {
        this.metadata = metadata;
        this.target = target;
        this.args = extractArgs(metadata.getMethod(), args);
    }

    private Object[] extractArgs(Method method, Object[] args) {
        if (!method.isVarArgs()) {
            return args;
        }
        Object[] varArgs = ObjectUtils.toObjectArray(args[args.length - 1]);
        Object[] combinedArgs = new Object[args.length - 1 + varArgs.length];
        System.arraycopy(args, 0, combinedArgs, 0, args.length - 1);
        System.arraycopy(varArgs, 0, combinedArgs, args.length - 1, varArgs.length);
        return combinedArgs;
    }

    public OperationInvocationMetadata getMetadata() {
        return metadata;
    }

    public Object getTarget() {
        return target;
    }

    public Object[] getArgs() {
        return args;
    }

    public Object getResult() {
        return result;
    }

    public void setResult(Object result) {
        this.result = result;
    }

    public Throwable getException() {
        return exception;
    }

    public void setException(Throwable exception) {
        this.exception = exception;
    }
}
